package com.tanhua.server.service;

import cn.hutool.core.convert.Convert;
import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.tanhua.common.mapper.QuestionnaireContentMapper;
import com.tanhua.common.mapper.QuestionnaireMapper;
import com.tanhua.common.mapper.QuestionnaireOptionsMapper;
import com.tanhua.common.mapper.QuestionnaireScoreMapper;
import com.tanhua.common.pojo.*;
import com.tanhua.common.utils.ChineseNumToIntUtil;
import com.tanhua.dubbo.server.api.QuestionnaireReportApi;
import com.tanhua.dubbo.server.enums.QuestionnaireReportType;
import com.tanhua.dubbo.server.pojo.QuestionnaireReport;
import com.tanhua.server.vo.*;
import io.jsonwebtoken.Jwts;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@Service
public class QuestionnaireService {
    @Reference(version = "1.0.0")
    private QuestionnaireReportApi questionnaireReportApi;
    @Autowired
    private QuestionnaireMapper questionnaireMapper;
    @Autowired
    private QuestionnaireContentMapper questionnaireContentMapper;
    @Autowired
    private QuestionnaireOptionsMapper questionnaireOptionsMapper;
    @Autowired
    private QuestionnaireScoreMapper questionnaireScoreMapper;
    @Value("${tanhua.server.questionnairecontent.number}")
    private String questionnaireContentNumber;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Value("${jwt.secret}")
    private String secret;

    /**
     * 查询所有问卷
     *
     * @return
     */
    public List<Questionnaire> queryAllQuestionnaires() {
        QueryWrapper<Questionnaire> queryWrapper = new QueryWrapper<>();
        queryWrapper.select(Questionnaire.class, i -> !i.getColumn().equals("updated")
                && !i.getColumn().equals("created"));
        List<Questionnaire> questionnaires = this.questionnaireMapper.selectList(queryWrapper);
        return questionnaires;
    }

    /**
     * 查询所有题目
     *
     * @return
     */
    public List<QuestionnaireContent> queryAllQuestionnaireContents() {
        QueryWrapper<QuestionnaireContent> queryWrapper = new QueryWrapper<>();
        queryWrapper.select(QuestionnaireContent.class, i -> !i.getColumn().equals("updated")
                && !i.getColumn().equals("created"));
        List<QuestionnaireContent> questionnaireContents = this.questionnaireContentMapper.selectList(queryWrapper);
        return questionnaireContents;
    }

    /**
     * 查询所有选项
     *
     * @return
     */
    public List<QuestionnaireOptions> queryAllQuestionnaireOptions() {
        QueryWrapper<QuestionnaireOptions> queryWrapper = new QueryWrapper<>();
        queryWrapper.select(QuestionnaireOptions.class, i -> !i.getColumn().equals("updated")
                && !i.getColumn().equals("created"));
        List<QuestionnaireOptions> questionnaireOptions = this.questionnaireOptionsMapper.selectList(queryWrapper);
        return questionnaireOptions;
    }

    /**
     * 根据试卷编号查询所有选项
     *
     * @param number
     * @return
     */
    public List<QuestionnaireOptions> queryOptionsByNumber(String number) {
        QueryWrapper<QuestionnaireOptions> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("questionnaire_number", number);
        List<QuestionnaireOptions> questionnaireOptions = this.questionnaireOptionsMapper.selectList(queryWrapper);
        return questionnaireOptions;
    }

    /**
     * 更新是否上锁
     *
     * @param questionnaireId
     * @return
     */
    public void updateIslock(String questionnaireId) {
        UpdateWrapper<Questionnaire> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("questionnaire_id", questionnaireId).set("isLock", 0);
        this.questionnaireMapper.update(null, updateWrapper);
    }

    /**
     * 单一问卷对象进行封装
     *
     * @param questionnaire
     * @return
     */
    public QuestionnaireVo queryByQuestionnaire(Questionnaire questionnaire) {
        QuestionnaireVo questionnaireVo = new QuestionnaireVo();
        List<QuestionnaireContentVo> questionnaireContentVoList = new ArrayList<>();
        //查询出所有的问题
        List<QuestionnaireContent> questionnaireContents = queryAllQuestionnaireContents();
        for (QuestionnaireContent questionnaireContent : questionnaireContents) {
            //根据questionId判断是否属于该问卷
            if (!questionnaireContent.getQuestionId().equals(questionnaire.getQuestionId())) {
                return questionnaireVo;
            }
            //题目内容对象
            QuestionnaireContentVo questionnaireContentVo = new QuestionnaireContentVo();
            //选项集合
            List<QuestionnaireOption> options = new ArrayList<>();
            //根据当前是第几道题目来查询出对应的所有选项
            List<QuestionnaireOptions> questionnaireOptions = queryOptionsByNumber(questionnaireContent.getNumber());
            //遍历选项集合,将其进行封装
            for (QuestionnaireOptions questionnaireOption : questionnaireOptions) {
                QuestionnaireOption option = new QuestionnaireOption();
                option.setId(questionnaireOption.getLetter());
                option.setOption(questionnaireOption.getContent());
                options.add(option);
            }
            //对集合中的每个问题进行封装
            questionnaireContentVo.setId(questionnaireContent.getNumber());
            questionnaireContentVo.setQuestion(questionnaireContent.getContent());
            questionnaireContentVo.setOptions(options);
            questionnaireContentVoList.add(questionnaireContentVo);
        }
        //对需要返回的问卷对象进行封装
        questionnaireVo.setId(questionnaire.getId());
        questionnaireVo.setCover(questionnaire.getCover());
        questionnaireVo.setIsLock(questionnaire.getIsLock());
        questionnaireVo.setLevel(questionnaire.getLevel());
        questionnaireVo.setName(questionnaire.getName());
        questionnaireVo.setReportId(questionnaire.getReportId());
        questionnaireVo.setStar(questionnaire.getStar());
        questionnaireVo.setQuestions(questionnaireContentVoList);

        return questionnaireVo;
    }

    /**
     * 根据所有问卷对象创建VO
     *
     * @return
     */
    public List<QuestionnaireVo> queryAll() {
        List<QuestionnaireVo> questionnaireVos = new ArrayList<>();
        List<Questionnaire> questionnaires = this.queryAllQuestionnaires();
        for (Questionnaire questionnaire : questionnaires) {
            QuestionnaireVo questionnaireVo = queryByQuestionnaire(questionnaire);
            questionnaireVos.add(questionnaireVo);
        }
        return questionnaireVos;
    }

    /**
     * 查询当前题目得分
     *
     * @param questionId
     * @param optionId
     * @return
     */
    public Integer getOptionsScore(String questionId, String optionId) {
        QueryWrapper<QuestionnaireScore> queryWrapper = new QueryWrapper<>();
        Map<String, String> map = new HashMap<>();
        map.put("questionnaire_number", questionId);
        map.put("options_letter", optionId);
        queryWrapper.allEq(map);
        QuestionnaireScore questionnaireScore = this.questionnaireScoreMapper.selectOne(queryWrapper);
        return questionnaireScore.getScore();
    }

    /**
     * 保存报告结果,提交请求中执行
     *
     * @param questionId
     * @param optionId
     * @return 报告id
     */
    public String saveOptionsScore(String questionId, String optionId, HttpServletRequest request) {
        //查询当前题目得分
        Integer optionsScore = this.getOptionsScore(questionId, optionId);
        String reportId = "";
        //根据token获取用户id
        String token = request.getHeader("Authorization");
        Map<String, Object> body = Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token)
                .getBody();
        //判断redis中当前用户所做的当前问卷的总分是否为空
        if (this.redisTemplate.opsForValue().get("QuestionnaireScore"+body.get("id").toString()) == null) {
            this.redisTemplate.opsForValue().set("QuestionnaireScore"+body.get("id").toString(), "0");
        }
        //获取做题前的初始得分
        Integer score = Integer.parseInt(this.redisTemplate.opsForValue().get("QuestionnaireScore"+body.get("id").toString()));
        //加上当前题目得分即为总得分
        Integer sumScore = optionsScore + score;
        //判断当前题目是否为最后一题
        if (ChineseNumToIntUtil.parse(questionId) < Integer.parseInt(questionnaireContentNumber)) {
            //更新得分
            this.redisTemplate.opsForValue().set("QuestionnaireScore"+body.get("id").toString(), sumScore.toString());

        }
        //最后一题执行的操作
        if (ChineseNumToIntUtil.parse(questionId) == Integer.parseInt(questionnaireContentNumber)) {
            //获取总得分
            this.redisTemplate.opsForValue().set("QuestionnaireScore"+body.get("id").toString(), sumScore.toString());
            Integer result = Integer.parseInt(this.redisTemplate.opsForValue().get("QuestionnaireScore"+body.get("id").toString()));
            //创建出报告对象
            QuestionnaireReport questionnaireReport = new QuestionnaireReport();
            //手动设置id
            questionnaireReport.setId(ObjectId.get());
            questionnaireReport.setUserId(Long.valueOf(body.get("id").toString()));
            questionnaireReport.setScore(result);
            if (result < 21) {
                questionnaireReport.setConclusion(QuestionnaireReportType.OWL.getContent());
                questionnaireReport.setCover(QuestionnaireReportType.OWL.getPicture());
            } else if (result >= 21 && result < 41) {
                questionnaireReport.setConclusion(QuestionnaireReportType.RABBIT.getContent());
                questionnaireReport.setCover(QuestionnaireReportType.RABBIT.getPicture());
            } else if (result >= 41 && result < 56) {
                questionnaireReport.setConclusion(QuestionnaireReportType.FOX.getContent());
                questionnaireReport.setCover(QuestionnaireReportType.FOX.getPicture());
            } else {
                questionnaireReport.setConclusion(QuestionnaireReportType.LION.getContent());
                questionnaireReport.setCover(QuestionnaireReportType.LION.getPicture());
            }
            //mongodb保存报告数据,返回报告id
            reportId=this.questionnaireReportApi.saveReport(questionnaireReport);
            //删除总得分
            this.redisTemplate.delete("QuestionnaireScore"+body.get("id").toString());

            //开启下一问卷的锁
            //根据试卷id进行更新
            if (this.redisTemplate.opsForValue().get("QuestionnaireId"+body.get("id").toString()) == null) {
                this.redisTemplate.opsForValue().set("QuestionnaireId"+body.get("id").toString(), "1");
            }
            Integer id = Integer.parseInt(this.redisTemplate.opsForValue().get("QuestionnaireId"+body.get("id").toString())) + 1;
            updateIslock(id.toString());
            //更新问卷表里的报告id字段
            updateReportId(reportId,this.redisTemplate.opsForValue().get("QuestionnaireId"+body.get("id").toString()));
            //所有问卷的锁都开启之后,删除问卷id
            this.redisTemplate.opsForValue().set("QuestionnaireId"+body.get("id").toString(),id.toString());
            if (id>=queryAllQuestionnaires().size()){
                this.redisTemplate.delete("QuestionnaireId"+body.get("id").toString());
            }
        }
        return reportId;
    }

    /**
     * 根据报告id查询数据并返回
     *
     * @param questionnaireReportId
     * @return
     */
    public QuestionnaireReportVo queryQuestionnaireReportById(String questionnaireReportId) {
        //响应对象
        QuestionnaireReportVo questionnaireReportVo = new QuestionnaireReportVo();
        //将查询到的报告数据封装成响应对象
        QuestionnaireReport questionnaireReport = this.questionnaireReportApi.queryByReportId(questionnaireReportId);
        questionnaireReportVo.setConclusion(questionnaireReport.getConclusion());
        questionnaireReportVo.setCover(questionnaireReport.getCover());
        //设置维度
        List<Dimension> dimensionList=new ArrayList<>();
        dimensionList.add(new Dimension("外向", "80%"));
        dimensionList.add(new Dimension("抽象", "70%"));
        dimensionList.add(new Dimension("理性", "60%"));
        dimensionList.add(new Dimension("判断", "90%"));
        questionnaireReportVo.setDimensions(dimensionList);
        //根据报告里的测试结果来查询与你相似
        //先查出符合条件的报告对象集合
        List<QuestionnaireReport> questionnaireReports = this.questionnaireReportApi.querySimilarYou(questionnaireReport.getConclusion());
        //根据报告对象里的userid获取头像,和userid一起封装成map
        List<SimilarYouUserInfo> similarYouUserInfoList=new ArrayList<>();
        for (QuestionnaireReport report : questionnaireReports) {
            UserInfo userInfo = this.userInfoService.queryUserInfoByUserId(report.getUserId());
            similarYouUserInfoList.add(new SimilarYouUserInfo(Convert.toInt(report.getUserId()), userInfo.getLogo()));
        }
        //设置与你相似
        questionnaireReportVo.setSimilarYou(similarYouUserInfoList);
        return questionnaireReportVo;
    }

    public void updateReportId(String recordId,String questionnaireId){
        UpdateWrapper<Questionnaire> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("questionnaire_id", questionnaireId).set("reportId", recordId);
        this.questionnaireMapper.update(null, updateWrapper);
    }

}
